package com.fdh.myjdbcutil;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.*;

/**
 * json工具类
 * <p>
 * 更新:增加更多方法,更完善
 *
 * @author fdh 2025.1.22 16:53
 * @version 1.1
 */
public class JSONUtil {
    private static final Gson gson = new Gson();

    /**
     * 对象转json字符串
     *
     * @param obj 对象
     * @return json字符串
     */
    public static String objectToJson(Object obj) {
        return gson.toJson(obj);
    }

    /**
     * json字符串转对象
     *
     * @param jsonStr  json字符串
     * @param objClass 对象Class
     * @param <T>      对象
     * @return 反序列化后的对象
     */
    public static <T> T jsonToObject(String jsonStr, Class<T> objClass) {
        return gson.fromJson(jsonStr, objClass);
    }

    /**
     * json字符串转对象
     *
     * @param jsonStr json字符串
     * @param type    对象类型
     * @return 反序列化后的对象
     */
    public static Object jsonToObject(String jsonStr, Type type) {
        return gson.fromJson(jsonStr, type);
    }

    /**
     * json字符串转List对象
     *
     * @param jsonStr      json字符串
     * @param elementClass List元素的Class
     * @param <T>          对象
     * @return 反序列化后的List对象
     */
    public static <T> List<T> jsonToListObject(String jsonStr, Class<T> elementClass) {
        return jsonToCollectionObject(jsonStr, List.class, elementClass);
    }

    /**
     * json字符串转集合对象
     *
     * @param jsonStr         json字符串
     * @param collectionClass 集合的Class
     * @param elementClass    集合元素的Class
     * @param <T>             集合对象
     * @param <E>             集合元素类型
     * @return 反序列化后的集合对象
     */
    public static <T extends Collection<E>, E> T jsonToCollectionObject(String jsonStr, Class<T> collectionClass, Class<E> elementClass) {
        Type type = getCollectionType(collectionClass, elementClass);
        return (T) jsonToObject(jsonStr, type);
    }

    /**
     * json字符串转Map对象
     *
     * @param jsonStr    json字符串
     * @param valueClass Map值的类型
     * @param <T>        Map对象
     * @param <E>        Map值类型
     * @return 反序列化后的Map对象
     */
    public static <T extends Map<String, E>, E> T jsonToMapObject(String jsonStr, Class<E> valueClass) {
        return (T) jsonToObject(jsonStr, new TypeToken<Map<String, E>>() {
        }.getType());
    }

    /**
     * 获取集合类型
     *
     * @param collectionClass 集合的Class
     * @param elementClass    集合元素的Class
     * @return 集合类型
     */
    public static Type getCollectionType(Class<? extends Collection<?>> collectionClass, Class<?> elementClass) {
        return TypeToken.getParameterized(collectionClass, elementClass).getType();
    }
}
